package com.quickboot.generate.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quickboot.common.entity.BaseEntity;
import com.quickboot.generate.consts.GenerateConst;
import com.quickboot.generate.entity.GenTable;
import com.quickboot.generate.entity.GenTableColumn;
import com.quickboot.generate.mapper.GenTableMapper;
import com.quickboot.generate.service.GenTableColumnService;
import com.quickboot.generate.service.GenTableService;
import com.quickboot.generate.vo.GenTableColumnVo;
import com.quickboot.generate.vo.GenTableVo;
import com.quickboot.generate.vo.JavaToMysqlTypeVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 代码生成-表 接口实现类
 *
 * @author Tellsea
 * @date 2022-11-25
 */
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class GenTableServiceImpl extends ServiceImpl<GenTableMapper, GenTable> implements GenTableService {

    private final GenTableColumnService genTableColumnService;

    @Override
    public Page<GenTableVo> queryList(Page page, GenTableVo entity) {
        return this.baseMapper.queryList(page, entity);
    }

    @Override
    public Page<GenTableVo> listByDataBase(Page page, GenTableVo entity) {
        return this.baseMapper.listByDataBase(page, entity);
    }

    @Override
    public GenTableVo queryById(Long id) {
        return this.baseMapper.queryById(id);
    }

    @Override
    public boolean saveEntity(GenTableVo entity) {
        List<GenTable> genTableList = JSON.parseArray(entity.getGenTableJson(), GenTable.class);
        boolean flag = true;
        for (GenTable table : genTableList) {
            List<GenTable> list = this.baseMapper.selectList(new LambdaQueryWrapper<GenTable>().eq(GenTable::getTableName, table.getTableName()));
            if (!CollectionUtils.isEmpty(list)) {
                this.baseMapper.deleteBatchIds(list.stream().map(GenTable::getId).collect(Collectors.toList()));
                for (GenTable genTable : list) {
                    genTableColumnService.remove(new LambdaQueryWrapper<GenTableColumn>().eq(GenTableColumn::getTableId, genTable.getId()));
                }
            }
            // 两个参数：table_name、table_comment
            table.setAuthor(entity.getAuthor());
            table.setParentPackage(entity.getParentPackage());
            table.setMavenModule(entity.getMavenModule());
            table.setModule(entity.getModule());
            table.setBusiness(StrUtil.toCamelCase(table.getTableName()));
            table.setEntity(StrUtil.upperFirst(table.getBusiness()));
            table.setEntityVo(StrUtil.addSuffixIfNot(table.getEntity(), "Vo"));
            table.setController(StrUtil.addSuffixIfNot(table.getEntity(), "Controller"));
            table.setService(StrUtil.addSuffixIfNot(table.getEntity(), "Service"));
            table.setServiceAttr(StrUtil.lowerFirst(table.getService()));
            table.setServiceImpl(StrUtil.addSuffixIfNot(table.getEntity(), "ServiceImpl"));
            table.setMapper(StrUtil.addSuffixIfNot(table.getEntity(), "Mapper"));
            table.setMapperXml(StrUtil.addSuffixIfNot(table.getEntity(), "Mapper"));
            table.setPageType(1L);
            table.setFormType(1L);
            table.setIsPc(1);
            table.setIsSave(1);
            table.setIsUpdate(1);
            table.setIsRemove(1);
            table.setIsRemoveBatch(1);
            table.setIsImport(1);
            table.setIsExport(1);
            int insertFlag = this.baseMapper.insert(table);
            // 表字段
            List<GenTableColumnVo> tableColumnVoList = genTableColumnService.queryByStructure(table.getTableName());
            for (GenTableColumnVo column : tableColumnVoList) {
                column.setTableId(table.getId());
                String mysqlType = column.getColumnType();
                column.setJavaField(StrUtil.toCamelCase(column.getColumnName()));
                if (CompareUtil.compare(column.getIsPk(), 1) == 0) {
                    table.setPkJavaField(column.getJavaField());
                    table.setPkColumnName(column.getColumnName());
                    this.baseMapper.updateById(table);
                    column.setIsQuery(0);
                    column.setIsForm(0);
                    column.setIsRequired(0);
                    column.setIsTable(0);
                    column.setIsLogicDelete(0);
                } else {
                    column.setIsQuery(GenerateConst.QUERY_EXCLUDE_LIST.contains(column.getJavaField()) ? 0 : 1);
                    column.setIsForm(GenerateConst.QUERY_EXCLUDE_LIST.contains(column.getJavaField()) ? 0 : 1);
                    column.setIsRequired(GenerateConst.QUERY_EXCLUDE_LIST.contains(column.getJavaField()) ? 0 : 1);
                    column.setIsTable(GenerateConst.QUERY_EXCLUDE_LIST.contains(column.getJavaField()) ? 0 : 1);
                    column.setIsLogicDelete(Objects.equals(column.getJavaField(), BaseEntity.deleteStatus) ? 1 : 0);
                }
                if (column.getColumnType().indexOf("(") > -1) {
                    mysqlType = column.getColumnType().substring(0, column.getColumnType().indexOf("("));
                }
                for (JavaToMysqlTypeVo javaToMysqlTypeVo : GenerateConst.JAVA_TYPE_TO_MYSQL_TYPE) {
                    if (javaToMysqlTypeVo.getTypeList().contains(mysqlType)) {
                        column.setJavaPackage(javaToMysqlTypeVo.getJavaPackage());
                        column.setJavaType(javaToMysqlTypeVo.getJavaType());
                    }
                }
                if ("remark".equals(column.getJavaField())) {
                    column.setHtmlType("textarea");
                } else {
                    column.setHtmlType("input");
                }
                if ("String".equals(column.getJavaType())) {
                    column.setQueryType("like");
                } else {
                    column.setQueryType("=");
                }
                column.setSort(0);
            }
            boolean saveBatchFlag = genTableColumnService.saveBatch(BeanUtil.copyToList(tableColumnVoList, GenTableColumn.class));
            flag = flag && ((insertFlag > 0) && saveBatchFlag);
        }
        return flag;
    }

    @Override
    public boolean updateEntity(GenTableVo entity) {
        List<GenTableColumn> columnList = JSON.parseArray(entity.getGenTableColumnJson(), GenTableColumn.class);
        int insertFlag = this.baseMapper.updateById(entity);
        boolean batchFlag = genTableColumnService.saveOrUpdateBatch(columnList);
        return (insertFlag > 0) && batchFlag;
    }
}
